/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.servlet;

import java.util.Locale;

import org.springframework.lang.Nullable;

/**
 * Interface to be implemented by objects that can resolve views by name.
 *
 * <p>View state doesn't change during the running of the application,
 * so implementations are free to cache views.
 *
 * <p>Implementations are encouraged to support internationalization,
 * i.e. localized view resolution.
 * 视图解析器ViewResolver 作用：视图解析
 * 视图解析器 ViewResolver
 * 视图的作用是渲染模型数据，将模型里的数据以某种形式呈现给用户。为了实现视图模型和具体实现技术的解耦，
 * SpringMVC 定义了一个高度抽象的 View 接口（视图）。它是无状态的(每一个请求都会创建一个 View)，不存在线程安全问题。
 * SpringMVC 中常用的视图类型有：URL 视图、JSON 视图、文档类视图、XML 视图。
 *
 * ViewResolver 负责将处理结果生成 View 视图，先根据逻辑视图名解析成物理视图名即具体的页面地址，再生成View视图对象，
 * 最后对 View 进行渲染将处理结果通过页面展示给用户。视图解析器的作用是将逻辑视图转为物理视图，
 * 所有的视图解析器都必须实现 ViewResolver 接口。
 *
 * 当然，有的场景也不需要视图解析器
 *
 * 	1)返回值是 String 类型，直接找到映射对应的 JSP，HTML，FreeMarker 或其他映射。默认请求是转发，也可以通过redirect 前缀指定为重定向
 * 	2)void（无返回值），因为我们在控制器方法的参数中可以直接使用原始 Servlet API 对象 HttpServletRequest 和 HttpServletResponse 对象，
 * 	所以无论是转发还是重定向都可以轻松实现，而无需使用返回值
 * 	3)ModeAndView 类型，不需要页面跳转，即基于 ajax 的异步请求，用 json 数据交互时，利用 @RequestBody 和 @ResponseBody 实现数据到 java 对象的绑定
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see org.springframework.web.servlet.view.InternalResourceViewResolver
 * @see org.springframework.web.servlet.view.ContentNegotiatingViewResolver
 * @see org.springframework.web.servlet.view.BeanNameViewResolver
 */
public interface ViewResolver {

	/**
	 * Resolve the given view by name.
	 * <p>Note: To allow for ViewResolver chaining, a ViewResolver should
	 * return {@code null} if a view with the given name is not defined in it.
	 * However, this is not required: Some ViewResolvers will always attempt
	 * to build View objects with the given name, unable to return {@code null}
	 * (rather throwing an exception when View creation failed).
	 * @param viewName name of the view to resolve
	 * @param locale the Locale in which to resolve the view.
	 * ViewResolvers that support internationalization should respect this.
	 * @return the View object, or {@code null} if not found
	 * (optional, to allow for ViewResolver chaining)
	 * @throws Exception if the view cannot be resolved
	 * (typically in case of problems creating an actual View object)
	 */
	@Nullable
	View resolveViewName(String viewName, Locale locale) throws Exception;

}
